#!/usr/bin/python

# Cheng-Chun Tu
# Dec 27, 2012

"""
This example creates a multi-controller network from
semi-scratch; note a topo object could also be used and
would be passed into the Mininet() constructor.
"""

from mininet.net import Mininet
from mininet.node import Controller, OVSKernelSwitch
from mininet.cli import CLI
from mininet.log import setLogLevel
from mininet.link import Intf

Switch = OVSKernelSwitch

#	Hosts		(hoX)		11:00:00:00:00:0X	11.0.0.X
#	Switches	(swX)		12:00:00:00:00:0X	12.0.0.X
#	MiddleBoxes (mbX)		13:00:00:00:00:0X	13.0.0.X

def addMiddleBox( net, N ):
	"Create MiddleBox mbN and add to net."
	name = 'mb%d' % N
	ip = '13.0.0.%d' % N
	mac = '13:00:00:00:00:%d' % N
	mb = net.addHost( name, ip=ip, mac=mac )
	return mb
	
def addHost( net, N ):
	"Create host hN and add to net."
	name = 'ho%d' % N
	ip = '11.0.0.%d' % N
	mac = '11:00:00:00:00:%d' % N
	ho = net.addHost( name, ip=ip, mac=mac )
	return ho

def addSwitch( net, name):
	return net.addSwitch(name)

def TopologyHotnet():
	"Create a network with multiple controllers."

	net = Mininet( controller=Controller, switch=Switch)
#	print "*** Creating controllers"
#	c1 = net.addController('c1', port=16699)

	print "*** Creating Switches"
	
	swList = []
	
	sw1 = addSwitch(net, 'sw1')
	sw2 = addSwitch(net, 'sw2')
	sw3 = addSwitch(net, 'sw3')
	sw4 = addSwitch(net, 'sw4')
	sw5 = addSwitch(net, 'sw5')
		
	swList.append(sw1)
	swList.append(sw2)
	swList.append(sw3)
	swList.append(sw4)
	swList.append(sw5)
	
	sw1.config(mac='12:00:00:00:00:01', ip='12.0.0.1')
	sw2.config(mac='12:00:00:00:00:02', ip='12.0.0.2')
	sw3.config(mac='12:00:00:00:00:03', ip='12.0.0.3')
	sw4.config(mac='12:00:00:00:00:04', ip='12.0.0.4')
	sw5.config(mac='12:00:00:00:00:05', ip='12.0.0.5')
 
	print "*** Creating MiddleBoxes"
	
	mbList = []
	mb1 = addMiddleBox(net, 1)
	mb2 = addMiddleBox(net, 2)
	mb3 = addMiddleBox(net, 3)
	mb4 = addMiddleBox(net, 4)
	
	mbList.append(mb1)
	mbList.append(mb2)
	mbList.append(mb3)
	mbList.append(mb4)
	
	print "*** Creating Hosts"
	
	hoList = []
	
	ho1 = addHost(net, 1)
	ho2 = addHost(net, 2)
	
	hoList.append(ho1)
	hoList.append(ho2)
	
	print "*** Creating Backbone Links"
	sw1.linkTo(sw2)
	sw1.linkTo(sw3)
	
	sw2.linkTo(sw4)
	sw3.linkTo(sw4)
	
	sw4.linkTo(sw5)
	
	print "*** Creating Distribution Links"
 	sw1.linkTo(ho1)
	
	sw2.linkTo(mb1)
	sw2.linkTo(mb2)
	
	sw3.linkTo(mb3)
	
	sw4.linkTo(mb4)
	
	sw5.linkTo(ho2)
	 
#	print "Connection Information"
#	intf = mb1.intf('mb1-eth0')
#	mb1.setMAC('00:00:00:00:01:11', intf)
#	print intf
	
	print "*** Static configuration"
	
	n = 0
	for mbox in mbList: 
		for intfname in mbox.intfList():
			print "Middlebox: ", mb, " interface: ", intfname
			mbox.setMAC('13:00:00:00:00:%d' % n, intfname)
			n = n + 1
	
#	n = 0
#	for intfname in mb1.intfList():
#		print "setting up interface:", intfname
#		mb1.setMAC('00:00:00:00:01:%d' % n, intfname)
#		n = n + 1
	
#	for intfname in sw1.intfList():
#		print "setting up interface:", intfname
#		sw1.setMAC('00:00:00:00:F1:%d' % n, intfname)
#		n = n + 1
	
#	print "*** show connection"
#	print "how ho1 connect to sw1:", ho1.connectionsTo(sw1)
	
	print "*** Starting network"
	net.build()
#	c1.start()
#	sw1.start( [ c1 ] )
#	sw2.start( [ c1 ] )

#	print "*** Testing network"
#	net.pingAll()

	print "*** Running CLI"
	CLI( net )

	print "*** Stopping network"
	net.stop()

if __name__ == '__main__':
	setLogLevel( 'info' )  # for CLI output
	TopologyHotnet()
